
#ifndef WISHMASTER_GENERICCAPTCHAFETCHER_IMPL_H
#define WISHMASTER_GENERICCAPTCHAFETCHER_IMPL_H

#include <QVariant>
#include <QDateTime>
#include "components/threadid.h"
#include "network/httpconnector.h"
#include "network/httprequest.h"
#include "log.h"

namespace Wishmaster
{
	class GenericCaptchaFetcherImpl : public QObject
	{
		Q_OBJECT
	public:
		GenericCaptchaFetcherImpl() : m_connector(0)
		{
		}

		void setConnector(Connector* connector)
		{
			m_connector = connector;
		}

		void setParams(const QVariantMap& params)
		{
			for(QVariantMap::const_iterator it = params.begin(); it != params.end(); ++it)
			{
				if(it.key() == "url_pattern")
				{
					m_urlPattern = it.value().toString();
				}
				else if(it.key() == "referer_pattern")
				{
					m_refererPattern = it.value().toString();
				}
				else if(it.key() == "url_thread_pattern")
				{
					m_urlThreadPattern = it.value().toString();
				}
				else if(it.key() == "referer_thread_pattern")
				{
					m_refererThreadPattern = it.value().toString();
				}
			}
		}

		void fetchCaptcha(const ThreadId& threadId)
		{
			Q_ASSERT(m_connector);
			QString urlstr = threadId.threadNumericId() == 0 ? m_urlThreadPattern : m_urlPattern;
			urlstr.replace("%CHAN%", threadId.chanName());
			urlstr.replace("%BOARD%", threadId.boardId());
			urlstr.replace("%THREADID%", QString::number(threadId.threadNumericId()));
			urlstr.replace("%RANDOM%", QString::number(qrand()));
			urlstr.replace("%TIME%", QString::number(QDateTime::currentDateTime().toTime_t()));
			//log(llDebug, "urlstr: %s", qPrintable(urlstr));
			QUrl url(urlstr);
			QString path = url.path();
			if(url.hasQuery())
			{
				path += '?';
				path += QString(url.encodedQuery());
			}
			//log(llDebug, "path: %s", qPrintable(path));
			RequestPtr request = m_connector->makeRequest(url.host(), path);
			HttpRequestPtr httpRequest = request.dynamicCast<HttpRequest>();
			if(httpRequest)
			{
				QString referer = threadId.threadNumericId() == 0 ? m_refererThreadPattern : m_refererPattern;
				referer.replace("%CHAN%", threadId.chanName());
				referer.replace("%BOARD%", threadId.boardId());
				referer.replace("%THREADID%", QString::number(threadId.threadNumericId()));
				httpRequest->setReferer(referer);
				//log(llDebug, "referer: %s", qPrintable(referer));
			}
			request->setProperty("thread_id", QVariant::fromValue<ThreadId>(threadId));
			connect(request.data(), SIGNAL(result(RequestPtr,QByteArray)), this, SLOT(captcha_result(RequestPtr,QByteArray)));

			m_connector->queue(request);
		}

	signals:
		void captcha(const ThreadId& id, const QByteArray& arr);

	private slots:
		void captcha_result(const RequestPtr& request, const QByteArray& arr)
		{
			ThreadId id = request->property("thread_id").value<ThreadId>();
			if(!id.isValid())
				return;
			log(llDebug, "Captcha for thread: %s:%s:%d", qPrintable(id.chanName()), qPrintable(id.boardId()), id.threadNumericId());
			if(request->contentType().startsWith("image"))
				emit captcha(id, arr);
			else
			{
				log(llWarning, "GenericCaptchaFetcher: invalid captcha content-type");
				emit captcha(id, QByteArray());
			}
		}

	private:
		Connector* m_connector;
		QString m_urlPattern;
		QString m_refererPattern;
		QString m_urlThreadPattern;
		QString m_refererThreadPattern;
	};
}

#endif

